package org.beetl.core.engine;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.beetl.core.aa.JacksonTest;
import org.beetl.core.exception.BeetlException;
import org.beetl.core.fun.MethodInvoker;
import org.beetl.core.fun.ObjectUtil;
import org.beetl.core.om.*;
import org.beetl.core.om.asm.AsmBeanFactory;

import java.lang.reflect.Modifier;

/**
 * 让Beetl支持record，未来计划内置，但考虑jdk8没有这个record语法，等过一段时间内置
 * 最新版本已经支持，这里暂时一个例子，如何扩展引擎支持特殊的属性访问
 */
public class RecordSupportEngine extends FastRuntimeEngine
{

    public RecordSupportEngine() {
        super();
        // 记录类型访问类
        AABuilder.defaultAAFactory = new MyRecordFactory();
    }

    public static class  MyRecordFactory extends DefaultAAFactory {


        public MyRecordFactory(){
			super();
			//换成实现
           this.reflectBeanAA = new ReflectRecordBeanAA();
        }

    }

	/**
	 * 同时支持POJO和Record
	 */
    public static class ReflectRecordBeanAA extends  ReflectBeanAA{

        @Override
        public Object value(Object o, Object name) {
            Class c = o.getClass();
            String key = (String) name;

            //record
            if (c.isRecord()) {
                try {
                    return c.getMethod(key).invoke(o);
                } catch (Exception e) {
                    throw new BeetlException(BeetlException.ATTRIBUTE_NOT_FOUND, "record " + c.getName() + " no field " + key, e);
                }
            }
            //普通类
            MethodInvoker mi = ObjectUtil.getInvokder(c, key);
            if(mi!=null){
                return mi.get(o);
            }else{
                throw new BeetlException(ObjectUtil.hasPrivateAttribute(c, key)
                        ? BeetlException.ATTRIBUTE_NOT_FOUND_PRIVATE : BeetlException.ATTRIBUTE_NOT_FOUND, key);
            }


        }
    }


}
